package context

import (
	"fmt"
	"pd/server/com"
	"pd/server/plugin/logger"

	"github.com/kylelemons/go-gypsy/yaml"
	"github.com/urfave/cli"
)

// func GetTxApiSecret() (apiSecretId string, apiSecretKey string) {
// 	apiSecretId = "AKIDZ0DE1f9QTIAyaz93h7UowoQwOfjjdL3Z"
// 	apiSecretKey = "LLBzpYDlKfngJjvvupeFeqoY3KL8jNo3"
// 	return
// }

type Config struct {
	appName                  string
	appVersion               string
	appCopyright             string
	debug                    bool
	configFile               string
	apiPort                  int
	apiHost                  string
	isLocal                  bool
	httpServerMode           string
	assetsPath               string
	awsAccessProductId       string
	awsSecretAccessProductId string
	awsRegion                string
	authApiUrl               string
	iotProductId             string
	keepaspiderApiUrl        string
	currBaseUrl              string
	ddyBaseUrl               string
	shardHost                string
	shardPort                int
	apiSecretId              string
	apiSecretKey             string
	userBaseUrl              string // 用户端域名
	testOpenId               string // 用户端域名
	mallApiBaseUrl           string
}

var c *Config

func NewConfig(ctx *cli.Context) *Config {
	if c == nil {
		c = &Config{}

		if ctx != nil && ctx.App != nil {
			c.appName = ctx.App.Name
			c.appCopyright = ctx.App.Copyright
			c.appVersion = ctx.App.Version
		}

		c.assetsPath = "./resource/assets/"
		c.SetValuesFromFile(GetConfigPath(ctx))
		c.SetValuesFromCliContext(ctx)
	}

	return c
}

func GetConfigPath(ctx *cli.Context) string {
	var configName = "x_ddy.yml"

	var defaultPath = fmt.Sprintf("/etc/%s", configName)

	var paths = []string{
		// main
		fmt.Sprintf("./server/app/ddy/resource/config/%s", configName),
		// config_test
		fmt.Sprintf("../resource/config/%s", configName),
		fmt.Sprintf("./config/%s", configName),
		fmt.Sprintf("./%s", configName),
		fmt.Sprintf("~/%s", configName),
		defaultPath,
	}

	var configPath string
	if ctx != nil && ctx.GlobalIsSet("config") {
		configPath = ctx.GlobalString("config")
		return com.ExpandedFilename(configPath)
	}

	for _, path := range paths {
		configPath = com.ExpandedFilename(path)

		logger.Infof("check config path -> `%s`", configPath)

		if com.FileExists(configPath) {
			logger.Infof("use config path -> `%s`", configPath)
			return configPath
		}
	}

	return defaultPath
}

func (c *Config) SetValuesFromFile(fileName string) error {
	yamlConfig, err := yaml.ReadFile(fileName)

	if err != nil {
		return err
	}

	c.configFile = fileName
	if debug, err := yamlConfig.GetBool("debug"); err == nil {
		c.debug = debug
	}

	if apiHost, err := yamlConfig.Get("api-host"); err == nil {
		c.apiHost = apiHost
	}

	if apiPort, err := yamlConfig.GetInt("api-port"); err == nil {
		c.apiPort = int(apiPort)
	}

	if httpServerMode, err := yamlConfig.Get("http-mode"); err == nil {
		c.httpServerMode = httpServerMode
	}

	if local, err := yamlConfig.GetBool("local"); err == nil {
		c.isLocal = local
	}

	if authApiUrl, err := yamlConfig.Get("auth-api-url"); err == nil {
		c.authApiUrl = authApiUrl
	}

	if iotProductId, err := yamlConfig.Get("iot-product-id"); err == nil {
		c.iotProductId = iotProductId
	}

	if keepaspiderApiUrl, err := yamlConfig.Get("keepaspider-api-url"); err == nil {
		c.keepaspiderApiUrl = keepaspiderApiUrl
	}
	if currBaseUrl, err := yamlConfig.Get("curr-base-url"); err == nil {
		c.currBaseUrl = currBaseUrl
	}

	if ddyBaseUrl, err := yamlConfig.Get("ddy-base-url"); err == nil {
		c.ddyBaseUrl = ddyBaseUrl
	}

	if apiSecretId, err := yamlConfig.Get("api-secret-id"); err == nil {
		c.apiSecretId = apiSecretId
	}

	if apiSecretKey, err := yamlConfig.Get("api-secret-key"); err == nil {
		c.apiSecretKey = apiSecretKey
	}

	if userBaseUrl, err := yamlConfig.Get("user-base-url"); err == nil {
		c.userBaseUrl = userBaseUrl
	}

	if testOpenId, err := yamlConfig.Get("test-open-id"); err == nil {
		c.testOpenId = testOpenId
	}

	if assetsPath, err := yamlConfig.Get("assets-path"); err == nil {
		c.assetsPath = assetsPath
	}

	if accessProductId, err := yamlConfig.Get("aws_access_apiSecretKey_id"); err == nil {
		c.awsAccessProductId = accessProductId
	}

	if secretProductId, err := yamlConfig.Get("aws_secret_access_apiSecretKey"); err == nil {
		c.awsSecretAccessProductId = secretProductId
	}

	if region, err := yamlConfig.Get("aws_region"); err == nil {
		c.awsRegion = region
	}

	if shardHost, err := yamlConfig.Get("shard-host"); err == nil {
		c.awsRegion = shardHost
	}

	if shardPort, err := yamlConfig.GetInt("shard-port"); err == nil {
		c.apiPort = int(shardPort)
	}
	if mallApiBaseUrl, err := yamlConfig.Get("mall-api-base-url"); err == nil {
		c.mallApiBaseUrl = mallApiBaseUrl
	}

	return nil
}

func (c *Config) SetValuesFromCliContext(ctx *cli.Context) error {
	if ctx == nil {
		return nil
	}

	if ctx.GlobalBool("debug") {
		c.debug = ctx.GlobalBool("debug")
	}

	if ctx.GlobalBool("local") {
		c.isLocal = ctx.GlobalBool("local")
	}

	if ctx.GlobalIsSet("api-host") || c.apiHost == "" {
		c.apiHost = ctx.GlobalString("api-host")
	}

	if ctx.GlobalIsSet("api-port") || c.apiPort == 0 {
		c.apiPort = ctx.GlobalInt("api-port")
	}

	if ctx.GlobalIsSet("http-mode") || c.httpServerMode == "" {
		c.httpServerMode = ctx.GlobalString("http-mode")
	}

	if ctx.GlobalIsSet("assets-path") || c.assetsPath == "" {
		c.assetsPath = ctx.GlobalString("assets-path")
	}

	if ctx.GlobalIsSet("aws_access_apiSecretKey_id"); c.awsAccessProductId == "" {
		c.awsAccessProductId = ctx.GlobalString("aws_access_apiSecretKey_id")
	}

	if ctx.GlobalIsSet("auth-api-url"); c.authApiUrl == "" {
		c.authApiUrl = ctx.GlobalString("auth-api-url")
	}
	if ctx.GlobalIsSet("iot-product-id"); c.iotProductId == "" {
		c.iotProductId = ctx.GlobalString("iot-product-id")
	}

	if ctx.GlobalIsSet("keepaspider-api-url"); c.keepaspiderApiUrl == "" {
		c.keepaspiderApiUrl = ctx.GlobalString("keepaspider-api-url")
	}
	if ctx.GlobalIsSet("curr-base-url"); c.currBaseUrl == "" {
		c.currBaseUrl = ctx.GlobalString("curr-base-url")
	}

	if ctx.GlobalIsSet("ddy-base-url"); c.ddyBaseUrl == "" {
		c.ddyBaseUrl = ctx.GlobalString("ddy-base-url")
	}

	if ctx.GlobalIsSet("api-secret-id"); c.apiSecretId == "" {
		c.apiSecretId = ctx.GlobalString("api-secret-id")
	}

	if ctx.GlobalIsSet("api-secret-key"); c.apiSecretKey == "" {
		c.apiSecretKey = ctx.GlobalString("api-secret-key")
	}

	if ctx.GlobalIsSet("user-base-url"); c.userBaseUrl == "" {
		c.userBaseUrl = ctx.GlobalString("user-base-url")
	}

	if ctx.GlobalIsSet("test-open-id"); c.testOpenId == "" {
		c.testOpenId = ctx.GlobalString("test-open-id")
	}
	if ctx.GlobalIsSet("aws_secret_access_apiSecretKey"); c.awsSecretAccessProductId == "" {
		c.awsSecretAccessProductId = ctx.GlobalString("aws_secret_access_apiSecretKey")
	}

	if ctx.GlobalIsSet("aws_region"); c.awsRegion == "" {
		c.awsRegion = ctx.GlobalString("aws_region")
	}

	if ctx.GlobalIsSet("shard-host") || c.apiHost == "" {
		c.apiHost = ctx.GlobalString("shard-host")
	}

	if ctx.GlobalIsSet("shard-port") || c.apiPort == 0 {
		c.apiPort = ctx.GlobalInt("shard-port")
	}
	if ctx.GlobalIsSet("mall-api-base-url"); c.mallApiBaseUrl == "" {
		c.mallApiBaseUrl = ctx.GlobalString("mall-api-base-url")
	}

	return nil
}

func (c *Config) AppName() string {
	return c.appName
}

func (c *Config) AppVersion() string {
	return c.appVersion
}

func (c *Config) AppCopyright() string {
	return c.appCopyright
}

func (c *Config) Debug() bool {
	return c.debug
}

func (c *Config) ConfigFile() string {
	return c.configFile
}

func (c *Config) ApiHost() string {
	return c.apiHost
}

func (c *Config) ApiPort() int {
	return c.apiPort
}

func (c *Config) HttpServerMode() string {
	return c.httpServerMode
}

func (c *Config) AssetsPath() string {
	return com.ExpandedFilename(c.assetsPath)
}

func (c *Config) ServerPath() string {
	return c.AssetsPath() + "/server"
}

func (c *Config) AuthApiUrl() string {
	return c.authApiUrl
}
func (c *Config) IotProductId() string {
	return c.iotProductId
}

func (c *Config) KeepaspiderApiUrl() string {
	return c.keepaspiderApiUrl
}
func (c *Config) CurrBaseUrl() string {
	return c.currBaseUrl
}

func (c *Config) ErpBaseUrl() string {
	return c.ddyBaseUrl
}

func (c *Config) ApiSecretId() string {
	return c.apiSecretId
}

func (c *Config) ApiSecretKey() string {
	return c.apiSecretKey
}

func (c *Config) UserBaseUrl() string {
	return c.userBaseUrl
}

func (c *Config) TestOpenId() string {
	return c.testOpenId
}

func (c *Config) HttpTemplatesPath() string {
	return c.ServerPath() + "/templates"
}

func (c *Config) AwsRegion() string {
	return c.awsRegion
}

func (c *Config) AwsAccessProductId() string {
	return c.awsAccessProductId
}

func (c *Config) AwsSecretAccessProductId() string {
	return c.awsSecretAccessProductId
}

func (c *Config) IsLocal() bool {
	return c.isLocal
}

func (c *Config) ShardHost() string {
	return c.shardHost
}

func (c *Config) ShardPort() int {
	return c.shardPort
}

func (c *Config) MallApiBaseURL() string {
	return c.mallApiBaseUrl
}
